#include <list>
#include <string>
#include <iostream>

using namespace std;

class Mediator;

class Colleague;

// 中介者抽象类
class Mediator {
public:
    Mediator() = default;

    virtual ~Mediator() {
        for (const auto &colleague : colleagueList) {
            delete colleague;
        }
    }

protected:
    list<Colleague *> colleagueList;

public:
    virtual void addColleague(Colleague *colleague) = 0;

    virtual void sendMessage(Colleague *sender, const string &message) = 0;
};

// 同事抽象类
class Colleague {
public:
    explicit Colleague(Mediator *mediator) : mediator(mediator) {
        mediator->addColleague(this);
    }

protected:
    Mediator *mediator = nullptr;

public:
    virtual void sendMessage(const string &message) = 0;

    virtual void receiveMessage(const string &message) = 0;
};

// 具体中介者类
class ConcreteMediator : public Mediator {
public:
    void addColleague(Colleague *colleague) override {
        colleagueList.push_back(colleague);
    }

    void sendMessage(Colleague *sender, const string &message) override {
        for (auto colleague : colleagueList) {
            if (colleague != sender) {
                colleague->receiveMessage(message);
            }
        }
    }
};

// 具体同事类
class ConcreteColleagueA : public Colleague {
public:
    explicit ConcreteColleagueA(Mediator *mediator) : Colleague(mediator) {
    }

public:
    void sendMessage(const string &message) override {
        cout << "Concrete Colleague A Send Message!" << endl;
        mediator->sendMessage(this, message);
    }

    void receiveMessage(const string &message) override {
        cout << "Concrete Colleague A Received Message: " << message << endl;
    }
};

class ConcreteColleagueB : public Colleague {
public:
    explicit ConcreteColleagueB(Mediator *mediator) : Colleague(mediator) {}

public:
    void sendMessage(const string &message) override {
        cout << "Concrete Colleague B Send Message!" << endl;
        mediator->sendMessage(this, message);
    }

    void receiveMessage(const string &message) override {
        cout << "Concrete Colleague B Received Message: " << message << endl;
    }
};

class ConcreteColleagueC : public Colleague {
public:
    explicit ConcreteColleagueC(Mediator *mediator) : Colleague(mediator) {}

public:
    void sendMessage(const string &message) override {
        cout << "Concrete Colleague C Send Message!" << endl;
        mediator->sendMessage(this, message);
    }

    void receiveMessage(const string &message) override {
        cout << "Concrete Colleague C Received Message: " << message << endl;
    }
};

void test01() {
    Colleague *a = nullptr;
    Colleague *b = nullptr;
    Colleague *c = nullptr;
    Mediator *mediator = nullptr;

    mediator = new ConcreteMediator();
    a = new ConcreteColleagueA(mediator);
    b = new ConcreteColleagueB(mediator);
    c = new ConcreteColleagueC(mediator);

    a->sendMessage("Hello World!");
    cout << "-------------------------------" << endl;
    b->sendMessage("How Are You!");
    cout << "-------------------------------" << endl;
    c->sendMessage("Celebrate A Happy!");

    delete mediator;
}

int main() {
    test01();

    return 0;
}